/*
 * Copyright (c) 2022 ASR Microelectronics (Shanghai) Co., Ltd. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <stdio.h>
#include "board.h"
#include "asr_rv32.h"
#include "asr_common.h"
#include "asr_uart.h"
#include "asr_pinmux.h"
#include "lega_at_api.h"
#include "arch.h"
#ifdef _SPI_FLASH_ENABLE_
#include "asr_flash_alg.h"
#include "asr_flash.h"
#endif
#ifdef STAR_MPU_ENABLE
//#include "panic_mpu.h"
#endif
#include "lega_wlan_api.h"
#include "los_interrupt.h"
#include "asr_alto_boot.h"

/***********************************************************
* init IRQ, set priority and enable IRQ
*
**********************************************************/
extern void intc_irq(void);
extern CRITICAL_FUNC_SEG void BLE_IRQHandler(void);
extern void CRYPTOCELL310_IRQHandler(void);
extern void D_APLL_UNLOCK_IRQHandler(void);
extern void D_SX_UNLOCK_IRQHandler(void);
extern void WDG_IRQHandler(void);
extern void SLEEP_IRQHandler(void);
extern void TIMER_IRQHandler(void);
extern void DMA_IRQHandler(void);
extern void UART0_IRQHandler(void);
extern void UART1_IRQHandler(void);
extern void UART2_IRQHandler();

static asr_uart_dev_t uart_config_struct  = {0};
void board_uart_init(void)
{
    asr_pinmux_config(PAD2,PF_UART1);
    asr_pinmux_config(PAD3,PF_UART1);

    asr_uart_struct_init(&uart_config_struct);
    uart_config_struct.port = UART1_INDEX;
    uart_config_struct.priv = at_handle_uartirq;
//set user define config
    uart_config_struct.config.baud_rate = UART_BAUDRATE_115200;
    uart_config_struct.config.flow_control = FLOW_CTRL_DISABLED;
//make config take effect
    asr_uart_init(&uart_config_struct);

    printf_uart_register(UART1_INDEX);
}

void pmp_init(void)
{
    int region = 0;
    
    /* chang itcm to 384k, pmp disabled temporarily
    printf("pmp_init\r\n");

    if(__config_PMPx(region, PMP_L | PMP_R | PMP_X, 0x00000000, 17))            //rom               128K    rom code
        printf("pmp_init region(%d) configure failed!\r\n", region);

    if(__config_PMPx(++region, PMP_L | PMP_R | PMP_W, 0x00080000, 16))          //itcm data         64K     data for ble rom + part-bss
        printf("pmp_init region(%d) configure failed!\r\n", region);

    if(__config_PMPx(++region, PMP_L | PMP_R | PMP_X, 0x00090000, 16))          //itcm code         64K     ram func
        printf("pmp_init region(%d) configure failed!\r\n", region);

    if(__config_PMPx(++region, PMP_L | PMP_R | PMP_W | PMP_X, 0x00000000, 26))  //riscv-reg         64M     systimer+eclic+jtag
        printf("pmp_init region(%d) configure failed!\r\n", region);

    if(__config_PMPx(++region, PMP_L | PMP_R | PMP_W | PMP_X, 0x20000000, 27))  //dtcm+sram         128M    stack+data+heap
        printf("pmp_init region(%d) configure failed!\r\n", region);

    if(__config_PMPx(++region, PMP_L | PMP_R | PMP_W, 0x40000000, 30))          //reg+ram           1G      reg+wifi+ble
        printf("pmp_init region(%d) configure failed!\r\n", region);

    if(__config_PMPx(++region, PMP_L | PMP_R | PMP_X, 0x80000000, 22))          //flash             4M      code
        printf("pmp_init region(%d) configure failed!\r\n", region);

    if(__config_PMPx(++region, PMP_L, 0x00000000, 32))                          //others            4G      N/A
        printf("pmp_init region(%d) configure failed!\r\n", region);
    */
}

void lega_devInit()
{

#if defined HARMONYOS_SUPPORT
    ota_roll_back_pro();
#endif

    ECLIC_Mode_Init();

    pmp_init();

#ifdef DCDC_PFMMODE_CLOSE
    lega_drv_close_dcdc_pfm();
#endif

#ifdef WIFI_BLE_INIT_ENABLE
    lega_drv_rco_cal();
#endif

    //init uart
    //board_uart_init();

    asr_cfg_boot_reset_type();

#ifdef WIFI_BLE_INIT_ENABLE

    lega_wlan_efuse_read();

    lega_sram_rf_pta_init();

    lega_recovery_phy_fsm_config();
#endif
#ifdef CFG_MIMO_UF
    //config to support smartconfig in MIMO scenario
    //lega_wlan_smartconfig_mimo_enable();
#endif

#ifdef CFG_TMMT_DETECT
    //config to enable temperature compensation
    //lega_wlan_enable_tmmt_compensation(60);
#endif

#ifdef SECURITY_ENGINE_INIT
    asr_security_engine_init();
#endif

}

extern uint8_t lega_sta_link_loss_1s_enable;
extern uint8_t lega_wifi_ps_disable_flag;
extern uint8_t lega_rx_ampdu_disable_flag;
extern uint8_t lega_fixed_edca_param;
extern uint8_t lega_weibo_disturb;
extern void lega_cca_adjust_enable(void);
volatile uint8_t weiqing_opt_flag = 0;
void lega_weibo_opt_enable(void)
{
    printf("\r\n lega_weibo_opt_enable \r\n");

    if(weiqing_opt_flag == 0)
    {
        weiqing_opt_flag = 1;
    }
    else
    {
        return;
    }
    lega_sta_link_loss_1s_enable = 1;
    lega_rx_ampdu_disable_flag = 1;
    lega_fixed_edca_param = 1;
    lega_weibo_disturb = 1;
    lega_wifi_ps_disable_flag = 1;
    lega_cca_adjust_enable();
}

#ifdef WIFI_BLE_INIT_ENABLE
extern void lega_drv_open_dcdc_pfm(void);
extern void lega_reset_rw_rf(void);
extern void lega_soc_wifi_ble_clk_disable(void);
extern void lega_enable_all_soc_interrupt(void);
#endif

void board_before_init(void)
{
    DisableDCache();
    DisableICache();

#ifdef _SPI_FLASH_ENABLE_
    asr_flash_init();
#endif

#ifdef STAR_MPU_ENABLE
    //mpu_init();
#endif

    EnableICache();
    EnableDCache();

#ifdef WIFI_BLE_INIT_ENABLE
    lega_drv_open_dcdc_pfm();
    lega_reset_rw_rf();
    //turn off all wifi/ble clock
    lega_soc_wifi_ble_clk_disable();
    //enable all soc interrupt
    lega_enable_all_soc_interrupt();
#endif
}
bool reset_flag;
/**************************************************
*  after task run use board_sys_init to init board
**************************************************/
int board_after_init(void)
{
    lega_devInit();
#ifdef RELEASE_DOMAIN
    //LOG("log_disable");
    lega_log_disable();
#endif
#ifdef WIFI_BLE_INIT_ENABLE
    tcpip_init( NULL, NULL );
    lega_wlan_init();
    #ifndef CFG_PTA_TEST
    #endif
#endif
    reset_flag = TRUE;

    asr_sys_reset_type_get();
    #if 0
    {
        extern int init_ble_task(void);
        init_ble_task();
    }
    #endif

    return 0;
}

/**************************************************
*  before task run use board_sys_init to init board
**************************************************/
void board_init(void)
{
#ifdef _SPI_FLASH_ENABLE_
    flash_partition_init();
#endif
}
